﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.Creation;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using YJKArch.Utils;
using YJKDragCurveJig;
using HYView;

namespace YJKArch.DimensionModule
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class CmdMapNameDim : YJKCommandManual
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		protected override Result YJKExcute(ExternalCommandData cmdData, ref string message, ElementSet elements)
		{
			CmdViewType types = (CmdViewType)111;
			if (SwitchView.SetUsableView(types, cmdData) != Autodesk.Revit.UI.Result.Succeeded)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			if (CmdMapNameDim._hWndRevit == null)
			{
				CmdMapNameDim._hWndRevit = new WindowHandle(Process.GetCurrentProcess().MainWindowHandle);
			}
			Autodesk.Revit.DB.View activeView = this.m_doc.ActiveView;
			if (!Helper.ViewValidating(cmdData.Application.ActiveUIDocument.Document, activeView, ref message))
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			string title = activeView.Document.Title;
			string name = activeView.Name;
			DimDate.FontFamily = AssistFunc.GetSystemFontTypeStringArray(this.m_doc);
			DlgMapNameDim dlgMapNameDim = new DlgMapNameDim(name, this.m_doc);
			if (dlgMapNameDim.ShowDialog() != DialogResult.OK)
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			Autodesk.Revit.Creation.Application create = this.m_app.Create;
			List<JigEdgeInfo> list = new List<JigEdgeInfo>();
			List<JigTextInfo> list2 = new List<JigTextInfo>();
			XYZ ptBase = null;
			if (!this.CreateDimData(create, activeView, dlgMapNameDim, ref ptBase, ref list, ref list2))
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			XYZ ptInsert = null;
			if (!DragCurveJigInterface.GetInsertPosition(cmdData, list, false, list2, false, ptBase, ref ptInsert))
			{
				return base.YJKExcute(cmdData, ref message, elements);
			}
			Transaction transaction = new Transaction(this.m_doc);
			transaction.Start("revit");
			ElementSet eleSet = new ElementSet();
			this.CreateDim(list, list2, activeView, ptInsert, ref eleSet);
			transaction.Commit();
			Transaction transaction2 = new Transaction(this.m_doc, "group");
			transaction2.Start();
			RevitVersionFuncs.NewGroup(this.m_doc, eleSet);
			transaction2.Commit();
			return base.YJKExcute(cmdData, ref message, elements);
		}

        private bool CreateDimData(Autodesk.Revit.Creation.Application appCreation, Autodesk.Revit.DB.View view, DlgMapNameDim dlg, ref XYZ ptBase, ref List<JigEdgeInfo> curveInfoList, ref List<JigTextInfo> textInfoList)
		{
			XYZ zero = XYZ.Zero;
			ptBase = zero;
			Element selectType = Helper.GetSelectType<TextNoteType>(this.m_doc, dlg.FontType);
			TextNoteType textNoteType = selectType as TextNoteType;
			Element selectType2 = Helper.GetSelectType<TextNoteType>(this.m_doc, dlg.proportionFontType);
			TextNoteType textNoteType2 = selectType2 as TextNoteType;
			double num = selectType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble() * (double)view.Scale;
			double num2 = selectType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
			string text = dlg.MapNameStr.Replace(" ", "");
			string text2 = dlg.proportionSelect.Replace(" ", "");
			byte[] bytes = Encoding.Default.GetBytes(text);
			double num3 = num * num2;
			double num4 = (double)bytes.Length * num3 / RevitDocumentExtension.GetVersionTextWidthFactory();
			double num5 = selectType2.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble() * (double)view.Scale;
			double num6 = selectType2.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
			double num7 = num5 * num6;
			XYZ xyz;
			XYZ xyz2;
			if (num < num5)
			{
				xyz = new XYZ(zero.X, zero.Y + Math.Abs(num - num5) / 1.5, zero.Z);
				xyz2 = new XYZ(zero.X + num4 + num3, zero.Y, zero.Z);
			}
			else
			{
				xyz = new XYZ(zero.X, zero.Y, zero.Z);
				xyz2 = new XYZ(zero.X + num4 + num3, zero.Y + Math.Abs(num - num5) / 1.5, zero.Z);
			}
			if (xyz2 == null)
			{
				return false;
			}
			XYZ basisX = XYZ.BasisX;
			XYZ basisY = XYZ.BasisY;
			double jigTextVerticalOffset = RevitDimensionExtension.GetJigTextVerticalOffset();
            JigTextInfo item = new JigTextInfo(textNoteType, xyz + basisY * num * jigTextVerticalOffset, basisX, basisY, (TextAlignFlags)1088, 0.001, text);
			textInfoList.Add(item);
			if (dlg.isChecked)
			{
                JigTextInfo item2 = new JigTextInfo(textNoteType2, xyz2 + basisY * num * jigTextVerticalOffset, basisX, basisY, (TextAlignFlags)1088, 1.0, text2);
				textInfoList.Add(item2);
				textInfoList.Add(item2);
				double num8 = num7 * (double)text2.Length / RevitDocumentExtension.GetVersionTextWidthFactory();
				num4 = num4 + num8 + num3;
			}
			XYZ startPoint = new XYZ(zero.X, zero.Y - 0.2 * (double)view.Scale / 100.0, zero.Z);
			XYZ endPoint = new XYZ(zero.X + num4, zero.Y - 0.2 * (double)view.Scale / 100.0, zero.Z);
			XYZ startPoint2 = new XYZ(zero.X, zero.Y - 0.4 * (double)view.Scale / 100.0, zero.Z);
			XYZ endPoint2 = new XYZ(zero.X + num4, zero.Y - 0.4 * (double)view.Scale / 100.0, zero.Z);
			JigEdgeInfo item3 = new JigEdgeInfo(startPoint, endPoint, 0.0);
			curveInfoList.Add(item3);
			if (dlg.traditionOrNational)
			{
				JigEdgeInfo item4 = new JigEdgeInfo(startPoint2, endPoint2, 0.0);
				curveInfoList.Add(item4);
			}
			return true;
		}

		private bool CreateDim(List<JigEdgeInfo> curveInfoList, List<JigTextInfo> textInfoList, Autodesk.Revit.DB.View view, XYZ ptInsert, ref ElementSet newgrpElements)
		{
			Transform identity = Transform.Identity;
			identity.Origin = ptInsert;
			identity.BasisX = view.RightDirection;
			identity.BasisY = view.UpDirection;
			identity.BasisZ = -view.ViewDirection;
			for (int i = 0; i < curveInfoList.Count; i++)
			{
				JigEdgeInfo jigEdgeInfo = curveInfoList[i];
				XYZ startPoint = Geometry.TransformPoint(jigEdgeInfo.StartPoint, identity);
				XYZ endPoint = Geometry.TransformPoint(jigEdgeInfo.EndPoint, identity);
				Curve curve = YJKLineEx.YJKGetBound(startPoint, endPoint);
				DetailCurve detailCurve = this.m_doc.Create.NewDetailCurve(view, curve);
				newgrpElements.Insert(detailCurve);
				for (int j = 0; j < RevitVersionFuncs.LineStyles(this.m_doc, detailCurve).Size; j++)
				{
					GraphicsStyle graphicsStyle = RevitVersionFuncs.LineStyles(this.m_doc, detailCurve).get_Item(j) as GraphicsStyle;
					int hashCode = -2000044.GetHashCode();
					if (i > 0)
					{
						hashCode = -2000042.GetHashCode();
					}
					if (graphicsStyle.GraphicsStyleCategory.GetHashCode() == hashCode)
					{
						detailCurve.LineStyle = graphicsStyle;
						break;
					}
				}
			}
			double num = double.MinValue;
			foreach (JigTextInfo jigTextInfo in textInfoList)
			{
				if (jigTextInfo.theTextNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble() > num)
				{
					num = jigTextInfo.theTextNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
				}
			}
			num = num / 3.0 * 304.8;
			foreach (JigTextInfo jigTextInfo2 in textInfoList)
			{
				XYZ origin = Geometry.TransformPoint(jigTextInfo2.Origin, identity);
				XYZ baseVec = jigTextInfo2.BaseVec;
				XYZ upVec = jigTextInfo2.UpVec;
				double num2 = jigTextInfo2.theTextNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
				double num3 = jigTextInfo2.theTextNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
				byte[] bytes = Encoding.Default.GetBytes(jigTextInfo2.StrText);
				double num4 = num2 * num3;
				double lineWidth = (double)bytes.Length * num4 * 1.2;
				TextNote textNode = this.m_doc.GetTextNode(this.m_doc.ActiveView, origin, baseVec, upVec, lineWidth, jigTextInfo2.TextAlign, jigTextInfo2.StrText);
				newgrpElements.Insert(textNode);
				textNode.TextNoteType = jigTextInfo2.theTextNoteType;
				double num5 = RevitElementExtension.GetTextNoteWidth(textNode) / (double)this.m_doc.ActiveView.Scale;
				double textVerticalOffset = RevitDimensionExtension.GetTextVerticalOffset(textNode.Symbol.GetParameter(BuiltInParameter.TEXT_SIZE).AsDouble() * 100.0);
				ElementTransformUtils.MoveElement(this.m_doc, textNode.Id, -textNode.UpDirection * textVerticalOffset);
				ElementTransformUtils.MoveElement(this.m_doc, textNode.Id, textNode.UpDirection * num);
			}
			return true;
		}

		public static WindowHandle _hWndRevit;
	}
}
